package cn.st4rlight.util.report.enums;

import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import org.apache.commons.lang3.StringUtils;

import com.google.common.collect.Lists;

import cn.st4rlight.util.enums.EnumUtil;
import cn.st4rlight.util.report.dto.TimeCondition;
import cn.st4rlight.util.report.enums.ability.IGetAllTimePoint;
import cn.st4rlight.util.time.DateTimes;
import lombok.AllArgsConstructor;
import lombok.Getter;

/**
 * @author st4rlight <st4rlight@163.com>
 * Created on 2025-09-15
 */
@Getter
@AllArgsConstructor
public enum TimeGroup implements IGetAllTimePoint {

    ALL("不以时间维度聚合", DateTimeFormatter.ofPattern(DateTimes.DATE_TIME_PATTERN)) {
        @Override
        public List<String> getAllTimePoints(Long beginTime, Long endTime) {
            return Lists.newArrayList();
        }
    },
    HOUR("分时", DateTimeFormatter.ofPattern(DateTimes.DATE_TIME_PATTERN)) {
        @Override
        public List<String> getAllTimePoints(Long beginTime, Long endTime) {
            int endHour = DateTimes.from(endTime).toLocalDateTime().getHour();
            LocalDateTime beginVar = DateTimes.from(beginTime).dayMin().toLocalDateTime();
            // 生成0～endHour的所有小时
            return IntStream.range(0, endHour + 1).mapToObj(itemHour -> {
                DateTimes tempVar = DateTimes.from(beginVar.plusHours(itemHour));
                return tempVar.toLocalDateTime().format(this.getTimeFormatter());
            }).collect(Collectors.toList());
        }
    },
    DAY("分日", DateTimeFormatter.ofPattern(DateTimes.DATE_PATTERN)) {
        @Override
        public List<String> getAllTimePoints(Long beginTime, Long endTime) {
            List<String> resultList = Lists.newArrayList();
            DateTimes dateTimes = DateTimes.from(beginTime).dayMin();
            while (dateTimes.toLong() <= endTime) {
                resultList.add(dateTimes.toLocalDateTime().format(this.getTimeFormatter()));
                dateTimes = dateTimes.plusDays(1);
            }
            return resultList;
        }
    },
    WEEK("分周", DateTimeFormatter.ofPattern(DateTimes.DATE_PATTERN)) {
        @Override
        public List<String> getAllTimePoints(Long beginTime, Long endTime) {
            // 分周是展示每周一
            List<String> resultList = Lists.newArrayList();
            DateTimes dateTimes = DateTimes.from(beginTime).firstDayOfWeek().dayMin();
            while (dateTimes.toLong() <= endTime) {
                resultList.add(dateTimes.toLocalDateTime().format(this.getTimeFormatter()));
                dateTimes = dateTimes.plusWeeks(1);
            }
            return resultList;
        }
    },
    MONTH("分月", DateTimeFormatter.ofPattern(DateTimes.MONTH_PATTERN)) {
        @Override
        public List<String> getAllTimePoints(Long beginTime, Long endTime) {
            List<String> resultList = Lists.newArrayList();
            DateTimes dateTimes = DateTimes.from(beginTime).firstDayOfMonth().dayMin();
            while (dateTimes.toLong() <= endTime) {
                resultList.add(dateTimes.toLocalDateTime().format(this.getTimeFormatter()));
                dateTimes = dateTimes.plusMonths(1);
            }
            return resultList;
        }
    }
    ;


    private final String desc;
    private final DateTimeFormatter timeFormatter;

    private static final Map<String, TimeGroup> NAME_CACHE =
            EnumUtil.buildKeyCache(TimeGroup.class, TimeGroup::name);

    public static TimeGroup of(String enumName) {
        return NAME_CACHE.getOrDefault(enumName, TimeGroup.ALL);
    }

    /**
     * 将原始的yyyy-MM-dd HH:mm:ss格式的时间，重新转换
     */
    public String formatDateTime(String originTime, String originPattern) {
        if (ALL.equals(this) || StringUtils.isBlank(originTime)) {
            return originTime;
        }
        return DateTimes.from(originTime, originPattern).toLocalDateTime().format(this.timeFormatter);
    }

    /**
     * 根据时间条件获取区间内的所有时间点
     * 如获取05.01-06.01的每一天的日期
     */
    public static List<String> getAllTimePoints(TimeCondition condition) {
        Long beginTime = condition.getBeginTime();
        Long endTime = condition.getEndTime();
        TimeGroup timeGroup = TimeGroup.of(condition.getGroupType());
        return timeGroup.getAllTimePoints(beginTime, endTime);
    }
}
